<template>
  <div v-loading="state.loading" :element-loading-background="state.elementLoadingBackground" style="width: 100%;"
       :title="propsCpt.emitPath ? state.paramVal?.map?.(v => optionsMapCpt.get(v)?.[propsCpt?.label] || state.paramVal).join('>') : optionsMapCpt.get(state.paramVal)?.[propsCpt?.label] || state.paramVal">
    <el-cascader
       style="width: 100%;"
       v-bind="$attrs"
       v-model="state.paramVal"
       :placeholder="((typeof $attrs.disabled !== 'undefined' && $attrs.disabled !== false) || state.formView) ? '' : ($attrs.placeholder ? $attrs.placeholder : `请选择${label}`)"
       :options="options"
       :clearable="isValue($attrs.clearable) ? $attrs.clearable : true"
       :filterable="isValue($attrs.filterable) ? $attrs.filterable : true"
       :props="propsCpt"
       :teleported="isValue($attrs.teleported) ? $attrs.teleported : false"
       :disabled="isValue($attrs.disabled) ? $attrs.disabled : state.formView"
    >
      <template #default="{ node, data }">
        <slot v-bind="{node, data}">
          <div class="cascader-item __text-ellipsis">
            <template v-if="panelMaxWidth">
              <el-tooltip
                  class="box-item"
                  effect="dark"
                  :content="data[propsCpt.label]"
                  placement="top"
              >
                <span>{{ data[propsCpt.label] }}</span>
              </el-tooltip>
            </template>
            <template v-else>
              <span>{{ data[propsCpt.label] }}</span>
            </template>
          </div>
        </slot>
      </template>
    </el-cascader>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  onMounted,
  reactive,
  watch,
  inject
} from 'vue'
import {isValue} from "@/utils/czr-util";
const emit = defineEmits(['emitParam'])
const props = defineProps({
  param: {},
  label: {},
  options: { type: Array, default: () => [] },
  props: {},
  panelMaxWidth: {
    default: null
  },
  static: {default: false}
})
const state = reactive({
  paramVal: props.param,
  defaultProps: {
    expandTrigger: 'hover' as const,
    checkStrictly: true,
    emitPath: false,
    label: 'label',
    value: 'value'
  },
  loading: true,
  elementLoadingBackground: inject('element-loading-background', null),
  formView: inject('form-view', false),
})
watch(() => state.paramVal, (n) => {
  emit('emitParam', n)
})
watch(() => props.param, (n) => {
  state.paramVal = n
})
watch(() => [props.options, props.static], () => {
  state.loading = false
})
const propsCpt = computed(() => {
  return props.props ? Object.assign(state.defaultProps, props.props) : state.defaultProps
})
const optionsMapCpt = computed(() => {
  const map = new Map()
  const deep = (arr) => {
    arr.forEach(v => {
      map.set(v[propsCpt.value.value], v)
      if (v.children?.length > 0) {
        deep(v.children)
      }
    })
  }
  deep(props.options)
  return map
})
onMounted(() => {
  if (props.static !== false || props.options?.length > 0) {
    state.loading = false
  }
})
</script>

<style scoped lang="scss">
:deep(.el-cascader__dropdown) {
  .el-cascader-node__label {
    $cmw: v-bind(panelMaxWidth);
    @if($cmw) {
      max-width: $cmw;
    }
    .cascader-item {
      width: 100%;
    }
  }
  .el-cascader__suggestion-item {
    height: auto !important;
  }
}

</style>
